package main

import (
	"bufio"
	"bytes"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strconv"
	"strings"
	"time"

	"github.com/shirou/gopsutil/cpu"
	"github.com/shirou/gopsutil/mem"
)

// 定义一个函数，用于在 goroutine 中执行
func printNumbers() {
	for i := 0; i < 5; i++ {
		time.Sleep(100 * time.Millisecond)
		fmt.Println("Number:", i)
	}
}

func main() {
	// 查看 Go 版本
	goVersion := runtime.Version()
	fmt.Printf("Go 版本: %s\n", goVersion)

	// 查看 Go 运行时的一些变量
	numCPU := runtime.NumCPU()
	fmt.Printf("可用的 CPU 核心数: %d\n", numCPU)

	goroutineCount := runtime.NumGoroutine()
	fmt.Printf("当前的 goroutine 数量: %d\n", goroutineCount)

	arch := runtime.GOARCH
	osName := runtime.GOOS
	fmt.Printf("架构: %s, 操作系统: %s\n", arch, osName)

	// 获取内存信息
	if osName == "linux" || osName == "darwin" {
		// 类 Unix 系统
		file, err := os.Open("/proc/meminfo")
		if err != nil {
			fmt.Printf("无法打开 /proc/meminfo 文件: %v\n", err)
		} else {
			defer file.Close()
			scanner := bufio.NewScanner(file)
			var memTotal, memFree uint64
			for scanner.Scan() {
				line := scanner.Text()
				if strings.HasPrefix(line, "MemTotal:") {
					parts := strings.Fields(line)
					if len(parts) >= 3 {
						memTotal, _ = strconv.ParseUint(parts[1], 10, 64)
					}
				} else if strings.HasPrefix(line, "MemFree:") {
					parts := strings.Fields(line)
					if len(parts) >= 3 {
						memFree, _ = strconv.ParseUint(parts[1], 10, 64)
					}
				}
			}
			if err := scanner.Err(); err != nil {
				fmt.Printf("读取 /proc/meminfo 文件出错: %v\n", err)
			}
			usedMem := memTotal - memFree
			fmt.Printf("总内存: %d kB\n", memTotal)
			fmt.Printf("当前使用内存: %d kB\n", usedMem)
			fmt.Printf("剩余内存: %d kB\n", memFree)
		}
	} else if osName == "windows" {
		// Windows 系统
		memInfo, err := mem.VirtualMemory()
		if err != nil {
			fmt.Printf("获取内存信息失败: %v\n", err)
		} else {
			fmt.Printf("总内存: %.2f GB\n", float64(memInfo.Total)/(1024*1024*1024))
			fmt.Printf("当前使用内存: %.2f GB\n", float64(memInfo.Used)/(1024*1024*1024))
			fmt.Printf("剩余内存: %.2f GB\n", float64(memInfo.Free)/(1024*1024*1024))
		}
	}

	if osName == "linux" || osName == "darwin" {
		// 获取服务器负载（仅适用于类 Unix 系统）
		// var loadavg [3]float64
		// err := syscall.Getloadavg(loadavg[:])
		// if err != nil {
		// 	fmt.Printf("获取服务器负载失败: %v\n", err)
		// } else {
		// 	fmt.Printf("最近 1 分钟负载平均值: %.2f\n", loadavg[0])
		// 	fmt.Printf("最近 5 分钟负载平均值: %.2f\n", loadavg[1])
		// 	fmt.Printf("最近 15 分钟负载平均值: %.2f\n", loadavg[2])
		// }
	} else if osName == "windows" {
		//cpuInfo()
		cpuInfoByExecInPowershell()
	} else {
		fmt.Println("此系统不支持获取服务器负载信息。")
	}

	// 创建一个 goroutine 来执行 printNumbers 函数
	go printNumbers()

	// 主线程继续执行其他任务
	for i := 0; i < 3; i++ {
		time.Sleep(200 * time.Millisecond)
		fmt.Println("Main:", i)
	}

	// 等待一段时间，确保 goroutine 有足够的时间执行
	time.Sleep(1 * time.Second)
	fmt.Println("Main function exiting")
}

func cpuInfo() {
	// 获取 Windows 系统的 CPU 使用率
	percent, err := cpu.Percent(time.Second, false)
	if err != nil {
		fmt.Printf("获取 CPU 使用率失败: %v\n", err)
	} else {
		fmt.Printf("当前 CPU 使用率: %.2f%%\n", percent[0])
	}
}

func cpuInfoByExecInCmd() {
	// 执行 wmic 命令获取 CPU 使用率
	cmd := exec.Command("wmic", "cpu", "get", "loadpercentage")
	var out bytes.Buffer
	cmd.Stdout = &out
	err := cmd.Run()
	if err != nil {
		fmt.Printf("执行命令失败: %v\n", err)
	} else {
		output := out.String()
		// 解析输出结果
		// 这里简单假设输出格式为 "LoadPercentage\nXX\n"
		lines := bytes.Split([]byte(output), []byte("\n"))
		if len(lines) > 1 {
			var load int
			_, err := fmt.Sscanf(string(lines[1]), "%d", &load)
			if err == nil {
				fmt.Printf("当前 CPU 使用率: %d%%\n", load)
			} else {
				fmt.Printf("解析输出失败: %v\n", err)
			}
		}
	}
}

func cpuInfoByExecInPowershell() {
	// 使用 PowerShell 命令获取 CPU 使用率
	cmd := exec.Command("powershell", "Get-WmiObject -Class Win32_Processor | Select-Object LoadPercentage")
	var out bytes.Buffer
	cmd.Stdout = &out
	err := cmd.Run()
	if err != nil {
		fmt.Printf("执行命令失败: %v\n", err)
	} else {
		output := out.String()
		// 解析输出结果
		// 这里简单假设输出格式为 "\nLoadPercentage\nXX\n"

		lines := bytes.Split([]byte(output), []byte("\n"))
		if len(lines) > 3 {
			var load int
			_, err := fmt.Sscanf(string(lines[3]), "%d", &load)
			if err == nil {
				fmt.Printf("当前 CPU 使用率: %d%%\n", load)
			} else {
				fmt.Printf("解析输出失败: %v\n", err)
			}
		}
	}
}

// findShutdown 递归查找名为 shutdown 的文件
// root := "/" // 根目录
//
//	findShutdown(root)
func findShutdown(root string) {
	filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			fmt.Printf("访问路径 %s 时出错: %v\n", path, err)
			return nil
		}
		if !info.IsDir() && info.Name() == "shutdown" {
			fmt.Printf("找到 shutdown 文件: %s\n", path)
		}
		return nil
	})
}

// showDirectoryTree 递归展示指定目录及其子目录的文件目录结构
// root := "/"
//
//	fmt.Printf("目录 %s 的文件目录结构如下：\n", root)
//	showDirectoryTree(root, 0)
func showDirectoryTree(root string, level int) {
	files, err := os.ReadDir(root)
	if err != nil {
		fmt.Printf("访问路径 %s 时出错: %v\n", root, err)
		return
	}

	for _, file := range files {
		for i := 0; i < level; i++ {
			fmt.Print("  ")
		}
		if file.IsDir() {
			fmt.Printf("├── %s/\n", file.Name())
			newPath := filepath.Join(root, file.Name())
			showDirectoryTree(newPath, level+1)
		} else {
			fmt.Printf("├── %s\n", file.Name())
		}
	}
}
